package com.glink.manage.sip.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.exception.GeneralSimpleException;
import com.glink.manage.common.CommonUtils;
import com.glink.manage.common.Constants;
import com.glink.manage.domain.PatrolIntelligentEquip;
import com.glink.manage.dto.sip.*;
import com.glink.manage.service.ConstructionWorkSiteService;
import com.glink.manage.service.PatrolIntelligentEquipService;
import com.glink.manage.sip.EquipSipService;
import com.glink.manage.vo.sip.*;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Objects;

/**
 * @author xum
 * @since 2024/8/29
 **/
@Service
@Slf4j
public class EquipSipServiceImpl implements EquipSipService {

    @Autowired
    private PatrolIntelligentEquipService intelligentEquipService;
    
    @Autowired
    @Lazy
    private ConstructionWorkSiteService constructionWorkSiteService;

    /*
    * 以下sip服务的信息要在配置文件中写死
    * */
    @Value("${proxySipServer.sipServerId:41010500002000000001}")
    private String proxySipServerId;
    @Value("${proxySipServer.sipServerField:4101050000}")
    private String proxySipServerField;
    @Value("${proxySipServer.sipServerIp:192.168.1.31}")
    private String proxySipServerIp;
    @Value("${proxySipServer.sipServerPort:5061}")
    private String proxySipServerPort;
    @Value("${proxySipServer.sipPassword:admin123}")
    private String proxySipPassword;
    @Value("${proxySipServer.intranetProxySipCode:29176544766600095860}")//在内网sip服务配置文件中配置
    private String intranetProxySipCode;

    @Value("${masterSipServer.sipServerId:41010500002000000002}")
    private String masterSipServerId;
    @Value("${masterSipServer.sipServerField:4101050000}")
    private String masterSipServerField;
    @Value("${masterSipServer.sipServerIp:58.210.193.22}")
    private String masterSipServerIp;
    @Value("${masterSipServer.sipServerPort:15062}")
    private String masterSipServerPort;
    @Value("${masterSipServer.sipPassword:admin123}")
    private String masterSipPassword;


    //外部网络sip服务地址：端口
    @Value("${sip.internalNetWorkSipServerAddress:https://192.168.1.31}")
    private String internalNetWorkSipServerAddress;
    @Value("${sip.internalNetWorkSipServerPort:18082}")
    private String internalNetWorkSipServerPort;

    @Value("${accessType.intranet_ip:192.168.1.31}")
    private String intranetIp;

    @Value("${accessType.internet_ip:58.210.193.22}")
    private String internetIp;

    /**
     * 获取sipServer信息
     */
    @Override
    public SipServerInfoVo getSipServerInfo(String lanType) {
        if (StringUtils.isBlank(lanType)) {
            return null;
        }
        SipServerInfoVo sipServerInfoVo = new SipServerInfoVo();
        //属于局域网
        if (StringUtils.equals(lanType, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01) || StringUtils.isEmpty(lanType) ){
            sipServerInfoVo.setSipServerId(proxySipServerId);
            sipServerInfoVo.setSipServerField(proxySipServerField);
            sipServerInfoVo.setSipServerIp(proxySipServerIp);
            sipServerInfoVo.setSipServerPort(proxySipServerPort);
            sipServerInfoVo.setSipPassword(proxySipPassword);
        }
        if (StringUtils.equals(lanType, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)){
            sipServerInfoVo.setSipServerId(masterSipServerId);
            sipServerInfoVo.setSipServerField(masterSipServerField);
            sipServerInfoVo.setSipServerIp(masterSipServerIp);
            sipServerInfoVo.setSipServerPort(masterSipServerPort);
            sipServerInfoVo.setSipPassword(masterSipPassword);
        }
        return sipServerInfoVo;
    }


    @Override
    public void ptzControl(PTZControlDTO dto) throws GeneralSimpleException {
        PatrolIntelligentEquip intelligentEquip = intelligentEquipService.getById(dto.getEquipId());
        if (Objects.isNull(intelligentEquip)) {
            throw new GeneralSimpleException("600201");
        }
        String url="";
        if (StringUtils.equals(intelligentEquip.getLan(),BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)){//设备直连
            url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/ptz/control/mediaServer";
            dto.setProxySipCode(intranetProxySipCode);
        }

        if (StringUtils.equals(intelligentEquip.getLan(),BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)){//设备非直连
            url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/ptz/control/mediaServer";
            dto.setProxySipCode(intelligentEquip.getSipCode());
        }
        String result = CommonUtils.sendPost(url,JSON.toJSONString(dto));
        if(StringUtils.isNotBlank(result)){
            WVPResult wvpResult = JSON.parseObject(result,WVPResult.class);
            if(Objects.nonNull(wvpResult) && !StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)){
                log.error("ptz操作失败：{}",wvpResult.getMsg());
                throw new GeneralSimpleException("600200");
            }
        }
    }

    @Override
    public RealStreamVO realPlay(ProxyCommonDTO dto)  throws GeneralSimpleException {
        PatrolIntelligentEquip intelligentEquip = intelligentEquipService.getById(dto.getEquipId());
        if (Objects.isNull(intelligentEquip)) {
            throw new GeneralSimpleException("600201");
        }
        if (StringUtils.equals(intelligentEquip.getIsOnline(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)) {
            throw new GeneralSimpleException("600301",intelligentEquip.getPatrolDeviceName());
        }

        // 点播的时候校验场站授权
        constructionWorkSiteService.checkGrantByObjId(intelligentEquip.getConstructionWorkSiteId());
        
        RealStreamVO vo = new RealStreamVO();
        String url="";
        if (StringUtils.equals(intelligentEquip.getLan(),BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)){//属于内网设备
             url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/play/start/" + intranetProxySipCode + "/" + dto.getChannelCode();
        }
        WVPResult wvpResult=null;
        if (StringUtils.equals(intelligentEquip.getLan(),BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)){//属于外网设备
             if (StringUtils.equals(intelligentEquip.getAgreement(), BaseCodeConstants.CodeType_AgreementType.KEY_AgreementType01)){
                 url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/play/start/" + intelligentEquip.getSipCode() + "/" + dto.getChannelCode();
             }else if (StringUtils.equals(intelligentEquip.getAgreement(), BaseCodeConstants.CodeType_AgreementType.KEY_AgreementType02)){
                 url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/push/getRtspPlayUrl/" + intelligentEquip.getPatrolDeviceCode() + "/" + dto.getChannelCode();
                 String result = CommonUtils.sendGet(url);
                 if(StringUtils.isNotBlank(result)){
                     wvpResult = JSON.parseObject(result,WVPResult.class);
                     if (!StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)){
                         log.error("RTSP协议点播，失败，code:{}, msg:{}", wvpResult.getCode(), wvpResult.getMsg());
                         throw new GeneralSimpleException("600300");
                     }
                     vo = JSON.parseObject(JSONObject.toJSONString(wvpResult.getData()), RealStreamVO.class);
                     if (StringUtils.isNotEmpty(dto.getType())){
                         //外网访问
                         if (StringUtils.equals(dto.getType(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)) {
                             vo = JSONObject.parseObject(wvpResult.getData().toString().replaceAll(intranetIp, internetIp), RealStreamVO.class);
                             return vo;
                         }
                     }
                     return vo;
                 }else {
                     throw new GeneralSimpleException("600300");
                 }
             }
        }
        String result = CommonUtils.sendGet(url);
        if(StringUtils.isNotBlank(result)){
             wvpResult = JSON.parseObject(result, WVPResult.class);
            if (!StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)){
                log.error("点播，失败，code:{}, msg:{}", wvpResult.getCode(), wvpResult.getMsg());
                throw new GeneralSimpleException(wvpResult.getCode(), wvpResult.getMsg());
            }
            vo = JSONObject.parseObject(wvpResult.getData().toString(), RealStreamVO.class);

            if (StringUtils.isNotEmpty(dto.getType())){
                //外网访问
                if (StringUtils.equals(dto.getType(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)) {
                    vo = JSONObject.parseObject(wvpResult.getData().toString().replaceAll(intranetIp, internetIp), RealStreamVO.class);
                    return vo;
                }
            }
        }
        return vo;
    }

    @Override
    public JSONObject realStop(ProxyCommonDTO dto) throws GeneralSimpleException {
        //注释-后端维护是否关闭播放
//        String url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/play/stop/" + dto.getProxySipCode() + "/" + dto.getChannelCode();
//        String result = CommonUtils.sendGet(url);
//        JSONObject jsonObject = JSON.parseObject(result);
//        if(Objects.nonNull(jsonObject)){
//            if(Integer.parseInt(jsonObject.get("code").toString()) !=0) {
//                throw new GeneralSimpleException("600202",jsonObject.get("msg").toString());
//            }else{
//                return JSON.parseObject(jsonObject.get("data").toString());
//            }
//        }
        log.info("关闭点播, {}",dto.getChannelCode());
        return null;
    }

    @Override
    public void operatePreset(OperatePresetDTO dto) throws GeneralSimpleException {
        String url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/notify/proxyMediaServer/operatePreset";
        String result = CommonUtils.sendPost(url,JSON.toJSONString(dto));
        if(StringUtils.isNotBlank(result)){
            WVPResult wvpResult = JSON.parseObject(result,WVPResult.class);
            if(Objects.nonNull(wvpResult) && !StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)){
                log.error("预置位操作失败：{}",wvpResult.getMsg());
                throw new GeneralSimpleException("600204");
            }
        }
    }

    @Override
    public List<OperatePresetListVO> getPtzPreset(OperatePresetListDTO dto) throws GeneralSimpleException {
        String url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/notify/proxyMediaServer/getPtzPreset";
        String result = CommonUtils.sendPost(url,JSON.toJSONString(dto));
        if(StringUtils.isNotBlank(result)){
            WVPResult<List<JSONObject>> wvpResult = JSON.parseObject(result,WVPResult.class);
            if(Objects.nonNull(wvpResult)){
                if(!StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)) {
                    log.error("获取预置位列表失败：{}", wvpResult.getMsg());
                    throw new GeneralSimpleException("600205");
                }
                List<OperatePresetListVO> operatePresetListVOList = Lists.newArrayList();
                List<JSONObject> data = wvpResult.getData();
                for (JSONObject datum : data) {
                    OperatePresetListVO operatePresetListVO = new OperatePresetListVO();
                    operatePresetListVO.setPresetName(datum.getString("presetName"));
                    operatePresetListVO.setPresetFlag(datum.getString("presetFlag"));
                    operatePresetListVO.setPresetNum(datum.getString("presetNum"));
                    operatePresetListVOList.add(operatePresetListVO);
                }
                return operatePresetListVOList;
            }
        }
        return Lists.newArrayList();
    }

    @Override
    public PresetPositionVO getPresetPosition(PresetPositionDTO dto) throws GeneralSimpleException {
        String url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/notify/proxyMediaServer/getPresetPosition";
        String result = CommonUtils.sendPost(url,JSON.toJSONString(dto));
        if(StringUtils.isNotBlank(result)){
            WVPResult wvpResult = JSON.parseObject(result, WVPResult.class);
            if(Objects.nonNull(wvpResult)){
                if(!StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)) {
                    log.error("获取摄像机角度失败：{}", wvpResult.getMsg());
                    throw new GeneralSimpleException("600205");
                }
                return JSON.parseObject(JSON.toJSONString(wvpResult.getData()), PresetPositionVO.class);
            }
        }
        return null;
    }

    @Override
    public NvrStorageVO findNvrStorageVO(NvrStorageDTO dto) throws GeneralSimpleException {
        NvrStorageVO vo = new NvrStorageVO();

        String url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/notify/proxyMediaServer/findNvrStorageVO";
        String result = CommonUtils.sendPost(url,JSON.toJSONString(dto));
        if(StringUtils.isNotBlank(result)){
            WVPResult wvpResult = JSON.parseObject(result, WVPResult.class);
            if(Objects.nonNull(wvpResult)){
                if(!StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)) {
                    log.error("获取Nvr存储失败：{}", wvpResult.getMsg());
                    throw new GeneralSimpleException("600206");
                }
                BeanUtils.copyProperties(wvpResult.getData(),vo);
            }
        }
        return vo;
    }

    @Override
    public void ptzControl3d(PTZ3dCommandDTO dto)throws GeneralSimpleException {
        String url = internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/ptz/control/selectionControlPtz";
        String requestBody=null;
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            requestBody = objectMapper.writeValueAsString(dto);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        String result = CommonUtils.sendPost(url,requestBody);
        WVPResult wvpResult = JSON.parseObject(result, WVPResult.class);
        if(Objects.nonNull(wvpResult)){
            if(!StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)) {
                log.error("3D框选云台控制失败：{}", wvpResult.getMsg());
                throw new GeneralSimpleException("600302");
            }
        }
    }

    @Override
    public AudioBroadcastResultVO broadcastApi(BroadcastDTO dto) throws GeneralSimpleException {
        AudioBroadcastResultVO audioBroadcastResultVO=new AudioBroadcastResultVO();
        PatrolIntelligentEquip intelligentEquip = intelligentEquipService.getById(dto.getEquipId());
        if (Objects.isNull(intelligentEquip)) {
            throw new GeneralSimpleException("600201");
        }
        if (StringUtils.equals(intelligentEquip.getIsOnline(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)) {
            throw new GeneralSimpleException("600301",intelligentEquip.getPatrolDeviceName());
        }
        String url="";
        if (StringUtils.equals(intelligentEquip.getLan(),BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)){//属于内网设备
            url = String.format(internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/play/broadcast/%s/%s?timeout=30&broadcastMode=true", intranetProxySipCode,dto.getChannelId());
        } else if (StringUtils.equals(intelligentEquip.getLan(),BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)) {//属于外网设备
            url = String.format(internalNetWorkSipServerAddress + ":" + internalNetWorkSipServerPort + "/api/play/broadcast/%s/%s?timeout=30&broadcastMode=true", intelligentEquip.getSipCode(),dto.getChannelId());
        }else {
            throw new GeneralSimpleException("600304",intelligentEquip.getPatrolDeviceName());
        }
        String result = CommonUtils.sendGet(url);
        if(StringUtils.isNotBlank(result)){
            WVPResult wvpResult = JSON.parseObject(result, WVPResult.class);
            if(Objects.nonNull(wvpResult)){
                if(!StringUtils.equals(wvpResult.getCode(), Constants.SipResultCode.SUCCESS_CODE)) {
                    log.error("获取语音广播命令失败：{}", wvpResult.getMsg());
                    throw new GeneralSimpleException("600303");
                }
                String jsonString = JSONObject.toJSONString(wvpResult.getData());
                ObjectMapper mapper = new ObjectMapper();
                try {
                    audioBroadcastResultVO = mapper.readValue(jsonString, AudioBroadcastResultVO.class);
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                //外网访问
                if (StringUtils.equals(dto.getType(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)) {
                    try {
                        audioBroadcastResultVO = mapper.readValue(jsonString.replaceAll(intranetIp, internetIp), AudioBroadcastResultVO.class);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException(e);
                    }
                    return audioBroadcastResultVO;
                }
            }
        }
        return audioBroadcastResultVO;
    }
}
